// 检查是否启用了 Unity 的程序化实例化功能
// UNITY_PROCEDURAL_INSTANCING_ENABLED 是 Unity 在启用 GPU Instancing（特别是程序化生成大量物体时）定义的宏
#if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
    // 声明一个 StructuredBuffer，类型是 float3，用于存储一系列的位置信息
    // 这个 Buffer 通常是在 C# 脚本中通过 Material.SetBuffer 传递进来的
    // 每个实例（比如一个方块、粒子等）会使用其中的一个位置
    StructuredBuffer<float3> _Positions;
#endif

// 定义一个浮点数 _Step，可能用于控制物体的缩放或其他属性
float _Step;

// 该函数用于配置每个实例的变换矩阵（通常是模型矩阵：Unity_ObjectToWorld）
// 在程序化实例化中，Unity 会在绘制每个实例前调用此函数
void ConfigureProcedural () {
    // 检查是否启用了程序化实例化
    #if defined(UNITY_PROCEDURAL_INSTANCING_ENABLED)
        // 从 _Positions 缓冲区中获取当前实例的位置
        // unity_InstanceID 是 Unity 自动提供的，表示当前正在处理的实例的索引
        float3 position = _Positions[unity_InstanceID];

        // 将 unity_ObjectToWorld 矩阵初始化为零矩阵
        // unity_ObjectToWorld 是 Unity 内置的变量，代表从物体空间到世界空间的变换矩阵
        unity_ObjectToWorld = 0.0;

        // 设置 unity_ObjectToWorld 矩阵的平移部分（_m03, _m13, _m23）和缩放/旋转部分的 w 分量（_m33 = 1.0 表示不进行统一的缩放或投影）
        // 这里将物体的位置设置为从 _Positions 缓冲区中读取的位置，并将矩阵的第四行设为 (0,0,0,1)，即标准的平移矩阵结构
        unity_ObjectToWorld._m03_m13_m23_m33 = float4(position, 1.0);

        // 设置物体的缩放：将矩阵的对角线元素 _m00, _m11, _m22 都设置为 _Step
        // 这相当于在 X/Y/Z 三个轴上均缩放 _Step 倍，通常用于控制实例的大小
        unity_ObjectToWorld._m00_m11_m22 = _Step;
    #endif
}

// 以下两个函数看起来是 Shader Graph 相关的占位函数，可能是为了兼容 Shader Graph 导出的 Shader
// 它们只是简单地将输入值原样输出，没有实际逻辑处理

// 一个处理 float3 类型数据的函数，输入 In，输出 Out，目前只是直接赋值
void ShaderGraphFunction_float (float3 In, out float3 Out) {
    Out = In;
}

// 一个处理 half3 类型数据的函数，与上面类似，但使用的是 half 精度
void ShaderGraphFunction_half (half3 In, out half3 Out) {
    Out = In;
}